﻿using AutoMapper;
using YDT_SeckillService.Applictions.DTOs;
using YDT_SeckillService.Applictions.Interfaces;
using YDT_SeckillService.Domain.Entities;
using YDT_SeckillService.Domain.Interfaces;

namespace YDT_SeckillService.Applictions.Services
{
    /// <summary>
    /// 秒杀应用服务实现 - 协调领域对象完成业务用例
    /// </summary>
    public class SeckillService : ISeckillService
    {
        private readonly ISeckillRepository _seckillRepository;
        private readonly ISeckillProductRepository _seckillProductRepository;
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数 - 依赖注入
        /// </summary>
        public SeckillService(ISeckillRepository seckillRepository,
                             ISeckillProductRepository seckillProductRepository,
                             IMapper mapper)
        {
            _seckillRepository = seckillRepository;
            _seckillProductRepository = seckillProductRepository;
            _mapper = mapper;
        }

        /// <summary>
        /// 根据ID获取秒杀活动
        /// </summary>
        public async Task<SeckillDto?> GetSeckillByIdAsync(Guid id)
        {
            var seckill = await _seckillRepository.GetByIdAsync(id);
            return _mapper.Map<SeckillDto>(seckill);
        }

        /// <summary>
        /// 根据日期获取秒杀活动
        /// </summary>
        public async Task<IEnumerable<SeckillDto>> GetSeckillsByDateAsync(DateOnly date)
        {
            var seckills = await _seckillRepository.GetByDateAsync(date);
            return _mapper.Map<IEnumerable<SeckillDto>>(seckills);
        }

        /// <summary>
        /// 获取所有秒杀活动
        /// </summary>
        public async Task<IEnumerable<SeckillDto>> GetAllSeckillsAsync()
        {
            var seckills = await _seckillRepository.GetAllAsync();
            return _mapper.Map<IEnumerable<SeckillDto>>(seckills);
        }

        /// <summary>
        /// 获取正在进行中的秒杀活动
        /// </summary>
        public async Task<IEnumerable<SeckillDto>> GetActiveSeckillsAsync()
        {
            var seckills = await _seckillRepository.GetActiveSeckillsAsync();
            return _mapper.Map<IEnumerable<SeckillDto>>(seckills);
        }

        /// <summary>
        /// 获取即将开始的秒杀活动
        /// </summary>
        public async Task<IEnumerable<SeckillDto>> GetUpcomingSeckillsAsync()
        {
            var seckills = await _seckillRepository.GetUpcomingSeckillsAsync();
            return _mapper.Map<IEnumerable<SeckillDto>>(seckills);
        }

        /// <summary>
        /// 分页查询秒杀活动
        /// </summary>
        public async Task<(IEnumerable<SeckillDto> Seckills, int TotalCount)> GetPagedSeckillsAsync(SeckillQueryDto query)
        {
            var (seckills, totalCount) = await _seckillRepository.GetPagedAsync(query.PageIndex, query.PageSize);
            var seckillDtos = _mapper.Map<IEnumerable<SeckillDto>>(seckills);
            return (seckillDtos, totalCount);
        }

        /// <summary>
        /// 创建秒杀活动
        /// </summary>
        public async Task<SeckillDto> CreateSeckillAsync(CreateSeckillDto createSeckillDto)
        {
            var seckill = new Seckill(
                createSeckillDto.TimeTitleUrl,
                createSeckillDto.SeckillDate,
                createSeckillDto.SeckillStartTime,
                createSeckillDto.SeckillEndTime
            );

            await _seckillRepository.AddAsync(seckill);
            return _mapper.Map<SeckillDto>(seckill);
        }

        /// <summary>
        /// 更新秒杀活动
        /// </summary>
        public async Task<SeckillDto?> UpdateSeckillAsync(Guid id, UpdateSeckillDto updateSeckillDto)
        {
            var seckill = await _seckillRepository.GetByIdAsync(id);
            if (seckill == null) return null;

            seckill.UpdateBasicInfo(
                updateSeckillDto.TimeTitleUrl,
                updateSeckillDto.SeckillDate,
                updateSeckillDto.SeckillStartTime,
                updateSeckillDto.SeckillEndTime
            );

            await _seckillRepository.UpdateAsync(seckill);
            return _mapper.Map<SeckillDto>(seckill);
        }

        /// <summary>
        /// 删除秒杀活动
        /// </summary>
        public async Task<bool> DeleteSeckillAsync(Guid id)
        {
            var seckill = await _seckillRepository.GetByIdAsync(id);
            if (seckill == null) return false;

            await _seckillRepository.DeleteAsync(id);
            return true;
        }

        /// <summary>
        /// 启用秒杀活动
        /// </summary>
        public async Task<SeckillDto?> EnableSeckillAsync(Guid id)
        {
            var seckill = await _seckillRepository.GetByIdAsync(id);
            if (seckill == null) return null;

            seckill.Enable();
            await _seckillRepository.UpdateAsync(seckill);
            return _mapper.Map<SeckillDto>(seckill);
        }

        /// <summary>
        /// 禁用秒杀活动
        /// </summary>
        public async Task<SeckillDto?> DisableSeckillAsync(Guid id)
        {
            var seckill = await _seckillRepository.GetByIdAsync(id);
            if (seckill == null) return null;

            seckill.Disable();
            await _seckillRepository.UpdateAsync(seckill);
            return _mapper.Map<SeckillDto>(seckill);
        }

        /// <summary>
        /// 添加秒杀商品
        /// </summary>
        public async Task<SeckillDto?> AddSeckillProductAsync(Guid seckillId, CreateSeckillProductDto productDto)
        {
            var seckill = await _seckillRepository.GetByIdAsync(seckillId);
            if (seckill == null) return null;

            seckill.AddSeckillProduct(
                productDto.ProductId,
                productDto.SeckillName,
                productDto.SeckillUrl,
                productDto.SeckillPrice,
                productDto.SeckillStock,
                productDto.SeckillLimit,
                productDto.SeckillDescription,
                productDto.SeckillType
            );

            await _seckillRepository.UpdateAsync(seckill);
            return _mapper.Map<SeckillDto>(seckill);
        }

        /// <summary>
        /// 移除秒杀商品
        /// </summary>
        public async Task<SeckillDto?> RemoveSeckillProductAsync(Guid seckillId, Guid seckillProductId)
        {
            var seckill = await _seckillRepository.GetByIdAsync(seckillId);
            if (seckill == null) return null;

            seckill.RemoveSeckillProduct(seckillProductId);
            await _seckillRepository.UpdateAsync(seckill);
            return _mapper.Map<SeckillDto>(seckill);
        }

        /// <summary>
        /// 减少秒杀商品库存
        /// </summary>
        public async Task<SeckillProductDto?> DecreaseSeckillProductStockAsync(Guid seckillProductId, int quantity)
        {
            var seckillProduct = await _seckillProductRepository.GetByIdAsync(seckillProductId);
            if (seckillProduct == null) return null;

            seckillProduct.DecreaseStock(quantity);
            await _seckillProductRepository.UpdateAsync(seckillProduct);
            return _mapper.Map<SeckillProductDto>(seckillProduct);
        }
    }
}
